"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 人为因素类
Case Name   :gs_dump数据库对象时数据对象被删除
Create At   : 2020-10-27
Owner       : n@ningyali
Description :
    1、创建数据库A，插入数据
    2、对数据库A进行gs_dump操作
    3、gs_dump操作未结束时删除数据库A
    4、创建数据库A，进行恢复
Expect      :
    1、gs_dump成功
    2、数据库删除成功
    3、恢复成功
History     :
    created: 2020/10/27  created by n@ningyali
    modify:   2023/09/26  @kyeleze 优化用例,减少偶现失败的问题
"""
import unittest
from yat.test import Node
from yat.test import macro

from testcase.utils.CommonSH import *
from testcase.utils.Common import *
from testcase.utils.Constant import *
from testcase.utils.ComThread import *

Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(3 != Primary_SH.get_node_num(), '非1+2环境不执行')
class GsDumpAndDelObject(unittest.TestCase):
    primary_sh = CommonSH('PrimaryDbUser')
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info('------------Opengauss_Reliability_Human_Case019:开始执行------------')
        self.primary_root_node = Node(node='PrimaryRoot')
        self.primary_user_node = Node(node='PrimaryDbUser')
        self.com = Common()
        self.Constant = Constant()
        self.db_name = 'db_humanfactor019'
        self.t_name = 'test_humanfactor019'
        self.dump_file_name = 'test_humanfactor019.sql'

    def test_main(self):
        self.log.info("---------------创建数据库A----------------")
        creat_db_cmd = f'''drop database if exists {self.db_name}; create database {self.db_name}; '''
        self.log.info(creat_db_cmd)
        msg = self.primary_sh.executDbSql(creat_db_cmd)
        self.log.info(msg)
        for err_msg in self.Constant.SQL_WRONG_MSG:
            self.assertNotIn(err_msg, msg)

        self.log.info("---------------插入数据----------------")
        create_table_cmd = f'''drop table if exists {self.t_name}; 
                            create table {self.t_name}(id int,name varchar(50));
                            '''
        insert_cmd = f'''insert into {self.t_name} values (generate_series(1,1000000), '测试humanfactor018');'''
        shell_cmd = f'source {macro.DB_ENV_PATH}; ' \
            f'gsql -d {self.db_name} -p {self.primary_user_node.db_port} -r -c "{create_table_cmd + insert_cmd}" '
        self.log.info(shell_cmd)
        insert_msg = self.primary_user_node.sh(shell_cmd).result()
        self.log.info(insert_msg)
        for err_msg in self.Constant.SQL_WRONG_MSG:
            self.assertNotIn(err_msg, insert_msg)

        self.log.info("-------------gs_dump前对表进行查询---------------")
        select_cmd = f'''select * from {self.t_name}'''
        shell_cmd = f"source {macro.DB_ENV_PATH}; " \
            f"gsql -d {self.db_name} -p {self.primary_user_node.db_port} -r -c '{select_cmd}' "
        self.log.info(shell_cmd)
        befor_dump_msg = self.primary_user_node.sh(shell_cmd).result()
        for err_msg in self.Constant.SQL_WRONG_MSG:
            self.assertNotIn(err_msg, befor_dump_msg)

        self.log.info("-------------对数据库A进行gs_dump操作---------------")
        dump_thread = ComThread(self.primary_sh.dumpFile, args=(self.dump_file_name, '', self.db_name, False))
        dump_thread.setDaemon(True)
        dump_thread.start()

        time.sleep(1)

        self.log.info("-------------gs_dump操作未结束时删除数据库A---------------")
        sql_cmd = f"drop database if exists {self.db_name};"
        self.log.info(sql_cmd)
        msg = self.primary_sh.executDbSql(sql_cmd)
        self.log.info(msg)
        for err_msg in self.Constant.SQL_WRONG_MSG:
            self.assertNotIn(err_msg, befor_dump_msg)

        self.log.info("---------------校验gs_dump结果----------------")
        dump_thread.join(60 * 5)
        dump_result = dump_thread.get_result()
        self.log.info(dump_result)
        self.assertTrue(dump_result)

        self.log.info("---------------创建数据库A----------------")
        sql_cmd = f'''create database {self.db_name}; '''
        self.log.info(sql_cmd)
        msg = self.primary_sh.executDbSql(sql_cmd)
        self.log.info(msg)
        for err_msg in self.Constant.SQL_WRONG_MSG:
            self.assertNotIn(err_msg, msg)

        self.log.info("-------------进行恢复操作---------------")
        self.com.file_sql_execute(self.primary_user_node, self.dump_file_name, 1, self.db_name)

        self.log.info("---------------恢复后查询表----------------")
        self.log.info(select_cmd)
        shell_cmd = f"source {macro.DB_ENV_PATH}; " \
            f"gsql -d {self.db_name} -p {self.primary_user_node.db_port} -r -c '{select_cmd}' "
        self.log.info(shell_cmd)
        after_dump_msg = self.primary_user_node.sh(shell_cmd).result()
        for err_msg in self.Constant.SQL_WRONG_MSG:
            self.assertNotIn(err_msg, after_dump_msg)
        self.assertEqual(befor_dump_msg, after_dump_msg)

    def tearDown(self):
        drop_cmd = f'''drop database if exists {self.db_name};'''
        self.log.info(drop_cmd)
        msg = self.primary_sh.executDbSql(drop_cmd)
        self.log.info(msg)

        shell_cmd = f"rm -rf {self.dump_file_name}; ls {self.dump_file_name}"
        self.log.info(shell_cmd)
        msg = self.primary_user_node.sh(shell_cmd).result()
        self.log.info(msg)
        self.log.info('------------Opengauss_Reliability_Human_Case019:执行完成------------')
